package com.mf.pte.utils;

import com.mf.pte.pojo.MyComponent;
import com.ptc.cipjava.intseq;
import com.ptc.cipjava.jxthrowable;
import com.ptc.pfc.pfcAssembly.Assembly;
import com.ptc.pfc.pfcAssembly.ComponentPath;
import com.ptc.pfc.pfcAssembly.pfcAssembly;
import com.ptc.pfc.pfcCommand.DefaultUICommandActionListener;
import com.ptc.pfc.pfcCommand.UICommandAccessListener;
import com.ptc.pfc.pfcComponentFeat.ComponentFeat;
import com.ptc.pfc.pfcFeature.Feature;
import com.ptc.pfc.pfcFeature.FeatureType;
import com.ptc.pfc.pfcFeature.Features;
import com.ptc.pfc.pfcModel.*;
import com.ptc.pfc.pfcModelItem.ModelItemType;
import com.ptc.pfc.pfcModelItem.ModelItems;
import com.ptc.pfc.pfcModelItem.Parameters;
import com.ptc.pfc.pfcSession.Session;
import com.ptc.pfc.pfcSolid.Solid;
import com.ptc.wfc.wfcAssembly.WAssembly;
import com.ptc.wfc.wfcAssembly.WComponentPaths;
import com.ptc.wfc.wfcModel.WModel;
import com.ptc.wfc.wfcSession.WSession;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BomExportUtil extends DefaultUICommandActionListener {


    private WSession wSession;

    private String filename;

    private List<MyComponent> components;
    private Map<String,MyComponent> componentMap;

    public BomExportUtil(WSession wSession, String filename) {
        this.wSession = wSession;
        this.filename = filename;

    }

    /**
     * 获取装配件的所有元素文件名称,包括隐含的元素以及族表元素
     * @throws jxthrowable
     */
    public void exportBom() throws jxthrowable {
        Model model = wSession.GetCurrentModel();
        Solid model1 = (Solid) model;

        //加入根组件
        MyComponent root = new MyComponent();
        root.setName(model1.GetFullName());
        root.setCount(1);
        components.add(root);
        componentMap.put("",root);

        // 递归整个模型
        exportBomRecursive(model1,new ArrayList<>());

        // 输出bom结果
        try {
            BufferedWriter writer = new BufferedWriter(new FileWriter(filename));
            writer.write("See things in list\n");
            writer.newLine();
            for (int i = 0; i < components.size(); i++) {
                writer.write(components.get(i).toString());
                writer.newLine();
            }

            writer.write("See things in map\n");
            writer.newLine();
            for (Map.Entry<String, MyComponent> stringMyComponentEntry : componentMap.entrySet()) {
                writer.write(stringMyComponentEntry.getKey().toString()+stringMyComponentEntry.getValue().toString());
                writer.newLine();
            }
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private MyComponent findComponentUnderTheSameParent(MyComponent myComponent) {
        for (MyComponent value : componentMap.values()) {
            if(value.getParentIdKey().equals(myComponent.getParentIdKey()) &&
                    value.getName().equals(myComponent.getName())){
                return value;
            }
        }
        return null;
    }

    private void exportBomRecursive(Solid solid,List<Integer> parentId) throws jxthrowable {
        Features features = solid.ListFeaturesByType(Boolean.TRUE, FeatureType.FEATTYPE_COMPONENT);
        ComponentFeat componentFeat;
        Feature feature;
        ModelDescriptor descriptor;
        for (int i = 0; i < features.getarraysize(); i++) {
            feature = features.get(i);
            if (!(feature instanceof ComponentFeat)) {
                continue;
            }

            componentFeat = (ComponentFeat) feature;
            descriptor = componentFeat.GetModelDescr();

            //当前件的id
            int id = componentFeat.GetId();
            String name = componentFeat.GetModelDescr().GetFullName();
            MyComponent myComponent = new MyComponent();
            myComponent.setParent_id(parentId);
            myComponent.setName(name);
            ArrayList<Integer> integers = new ArrayList<>(parentId);
            integers.add(id);
            myComponent.setId(integers);
            myComponent.setCount(1);

            MyComponent brother = findComponentUnderTheSameParent(myComponent);
            if (brother != null) {
                brother.increaseCount();
            } else
            {
                components.add(myComponent);
                componentMap.put(myComponent.getIdKey(),myComponent);
            }


            ModelType modelType = descriptor.GetType();
            if(modelType == ModelType.MDL_ASSEMBLY){
                Model model = wSession.GetModelFromDescr(descriptor);
                exportBomRecursive((Solid) model,myComponent.getId());
            }
        }
    }

    private void exportGenericBOM() throws jxthrowable {
        BOMExportInstructions bomExport = pfcModel.BOMExportInstructions_Create();
        Model model = wSession.GetCurrentModel();
        model.Export(filename,bomExport);
    }

    @Override
    public void OnCommand() throws jxthrowable {
        components = new ArrayList<>();
        componentMap = new HashMap<>();
        // 调用自己的方法导出txt格式的bom
        exportBom();
        // creo自带的导出格式
//        exportGenericBOM();
        // 参数访问测试
//        parameterTest();
        // 装配路径测试
//        componentIdTest();
    }

    private void parameterTest() throws jxthrowable {
        Model model = wSession.GetCurrentModel();
        if(model!=null){
            Parameters parameters = model.ListParams();
            for (int i = 0; i < parameters.getarraysize(); i++) {
                System.out.println(parameters.get(i).GetName());
            }
        }
    }

    private void componentIdTest() throws jxthrowable {
        Model model = wSession.GetCurrentModel();
        Assembly model1 = (Assembly) model;
        intseq intseq = com.ptc.cipjava.intseq.create();
        ComponentPath componentPath = pfcAssembly.CreateComponentPath(model1, intseq);
        com.ptc.cipjava.intseq intseq1 = componentPath.GetComponentIds();
        System.out.println((intseq.getarraysize() ==intseq1.getarraysize() ));
        for (int i = 0; i < intseq1.getarraysize(); i++) {
            System.out.println(intseq1.get(i));
        }
    }

}
